function [nFs, mXY, vShut, bReload] = Intensity_Levels(bAutoLoad)
% GalvoScanControl
% Scan script template: Intensity_Levels
% Description:
% Run a pulse train at current (fixed) location with user-defined;
%       number of cycles (#)
%       voltage range (min-max V)
%       voltage step (dV)
%       frequency (Hz)
%       duty-cycle (ms)
%

% Scan scripts should return four variables (in this order):
%  nFs      The sample rate (1/sec between scan points)
%  mXY      A matrix with two columns in the format [X Y], where
%               X  are x-positions
%               Y  are y-positions
%           The unit of this matrix is millimeters, relative to the origin
%  vShut    Vector with same length as mXY where values indicate shutter
%           open/close state (when a shutter is controlled) or the beam
%           intensity (when the output is directed to an intensity
%           modulated laser module, e.g. Coherent CUBE).
%           Note: Values of vShut should not exceed +/- 5V. Values beyond
%           these limits will be fixed at +/- 5V by the software.
%  bReload  Boolean indicating whether the script should be re-loaded each
%           time before executing. Setting this to true (1) will decrease
%           the repetition rate and should only be used for long programs
%           that are not executed at high frequency.


persistent p_sTrains p_sFreq p_sMinV p_sMaxV p_sVStep p_sDutyCycle p_sRandOrder
bReload = 1;

% Default values
if isempty(p_sMinV), p_sMinV = '0'; end
if isempty(p_sMaxV), p_sMaxV = '5'; end
if isempty(p_sVStep), p_sVStep = '.5'; end
if isempty(p_sFreq), p_sFreq = '2'; end
if isempty(p_sDutyCycle), p_sDutyCycle = '10'; end
if isempty(p_sTrains), p_sTrains = '12'; end
if isempty(p_sRandOrder), p_sRandOrder = '1'; end

if ~bAutoLoad
    cAnswers = inputdlg({ 'Minimum intensity (0-5 V)', ...
        'Maximum intensity (0-5 V)', ...
        'Intensity step (V)', ...               % V between each discrete value
        'Frequency (Hz)', ...
        'Duty cycle (ms)', ...                  % pulse on duration (ms)
        'Train repetitions (#)', ...            % number of times to repeat train of length min:step:max
        'Randomize order (0=no, 1=yes)' }, ...   % randomize order
        'Intensity Levels', ones(1, 7), ...
        {p_sMinV, p_sMaxV, p_sVStep, p_sFreq, p_sDutyCycle, p_sTrains, p_sRandOrder});
    if isempty(cAnswers), return, end
    
    % For some reason, closing the input dialog takes forever.
    % Placing this pause here prevents this.
    pause(0.1)
    
    p_sMinV = cAnswers{1};
    p_sMaxV = cAnswers{2};
    p_sVStep = cAnswers{3};
    p_sFreq = cAnswers{4};
    p_sDutyCycle = cAnswers{5};
    p_sTrains = cAnswers{6};
    p_sRandOrder = cAnswers{7};
end

nTrains = str2double(p_sTrains);
% Make sure nTrains is an integer > 0
nTrains = ceil(nTrains);
p_sTrains = num2str(nTrains);

nFreq = str2double(p_sFreq);
nDutyCycle = str2double(p_sDutyCycle);
nMinV = str2double(p_sMinV);
nMaxV = str2double(p_sMaxV);
nVStep = str2double(p_sVStep);
bRandOrder = str2double(p_sRandOrder);

% Generate analog trace from current pulse train parameters
nPulseUp = nDutyCycle; % ms
nPeriod = (1 / nFreq) * 1000; % ms
nPulseDown = nPeriod - nPulseUp;

vShutInt = nMinV:nVStep:nMaxV;

% Truncate intensity to 0 - 5 V
vShutInt(vShutInt < 0) = 0;
vShutInt(vShutInt > 5) = 5;

% Single pulse
vOpen = ones(nPulseUp, 1);      % Open period
vClosed = zeros(nPulseDown, 1); % Close period (0V)

% Repeat pulse train for N number of trains
if nTrains > 1
    vShutInt = repmat(vShutInt, 1, nTrains);
end

% Randomize order of pulses
if bRandOrder
    vShutInt = vShutInt(randperm(length(vShutInt)));
end

% Compose pulse train
vShut = [];
for i = 1:length(vShutInt)
    vShut = [vShut; vOpen .* vShutInt(i); vClosed];
end
vShut = [vShut; 0];
nFs = 1000;
mXY = zeros(length(vShut), 2);

return
